package shopping;

import java.util.*;

public class ConcreteShoppingMall implements ShoppingMall {
    private List<Member> members;
    private Map<String, List<OrderRecord>> memberOrders;

    private static class OrderRecord {
        String memberId;
        ProductCategory category;
        int originalPrice;
        double actualPayment;

        OrderRecord(String memberId, ProductCategory category, int originalPrice, double actualPayment) {
            this.memberId = memberId;
            this.category = category;
            this.originalPrice = originalPrice;
            this.actualPayment = actualPayment;
        }
    }

    public ConcreteShoppingMall() {
        members = new ArrayList<>();
        memberOrders = new HashMap<>();
    }

    @Override
    public void addMember(String info) {
        String[] parts = info.split(" ");
        String memberId = parts[0];
        String type = parts[3];
        
        Member member;
        if (type.equals("G")) {
            member = new GoldCardMember(info);
        } else {
            member = new SilverCardMember(info);
        }
        members.add(member);
        memberOrders.put(memberId, new ArrayList<>());
    }

    @Override
    public void addMember(List<String> infos) {
        for (String info : infos) {
            addMember(info);
        }
    }

    @Override
    public Member getMember(String memberId) {
        for (Member member : members) {
            if (member.getMemberId().equals(memberId)) {
                return member;
            }
        }
        return null;
    }

    @Override
    public double placeOrder(String memberId, int cost, ProductCategory category) {
        Member member = getMember(memberId);
        if (member == null) return 0;
        
        double actualPayment = member.consume(cost);
        memberOrders.get(memberId).add(new OrderRecord(memberId, category, cost, actualPayment));
        return actualPayment;
    }

    @Override
    public List<String> getMemberRecords(String memberId) {
        List<String> records = new ArrayList<>();
        List<OrderRecord> orders = memberOrders.get(memberId);
        if (orders == null) return records;
        
        for (OrderRecord order : orders) {
            records.add(String.format("%s %s %d %.0f", 
                order.memberId, order.category, order.originalPrice, order.actualPayment));
        }
        return records;
    }

    @Override
    public List<String> getCostByCategory() {
        Map<ProductCategory, CategoryStats> stats = new EnumMap<>(ProductCategory.class);
        for (ProductCategory category : ProductCategory.values()) {
            stats.put(category, new CategoryStats());
        }
        
        for (List<OrderRecord> orders : memberOrders.values()) {
            for (OrderRecord order : orders) {
                CategoryStats categoryStats = stats.get(order.category);
                categoryStats.count++;
                categoryStats.totalPayment += order.actualPayment;
            }
        }
        
        List<String> result = new ArrayList<>();
        for (ProductCategory category : ProductCategory.values()) {
            CategoryStats categoryStats = stats.get(category);
            result.add(String.format("%s %d %.0f", 
                category, categoryStats.count, categoryStats.totalPayment));
        }
        return result;
    }

    private static class CategoryStats {
        int count = 0;
        double totalPayment = 0;
    }

    @Override
    public List<String> getMemberRecordByGenderAndAge(char gender, int lowerAge, int upperAge) {
        List<MemberStats> memberStatsList = new ArrayList<>();
        
        for (Member member : members) {
            if (member.getGender() == gender && 
                member.getAge() >= lowerAge && 
                member.getAge() <= upperAge) {
                double totalCost = member.getTotalCost();
                if (totalCost > 0) {  // Only include members who have consumed
                    memberStatsList.add(new MemberStats(member));
                }
            }
        }
        
        Collections.sort(memberStatsList);
        
        List<String> result = new ArrayList<>();
        for (MemberStats stats : memberStatsList) {
            result.add(stats.member.getGenderAgeCost());
        }
        return result;
    }

    private static class MemberStats implements Comparable<MemberStats> {
        Member member;
        
        MemberStats(Member member) {
            this.member = member;
        }
        
        @Override
        public int compareTo(MemberStats other) {
            int ageCompare = Integer.compare(member.getAge(), other.member.getAge());
            if (ageCompare != 0) return ageCompare;
            
            // If ages are equal, sort by total cost in descending order
            return Double.compare(other.member.getTotalCost(), member.getTotalCost());
        }
    }

    @Override
    public double getTotalCost(String memberId) {
        Member member = getMember(memberId);
        return member != null ? member.getTotalCost() : 0;
    }

    @Override
    public double getTotalIncome() {
        double total = 0;
        for (Member member : members) {
            total += member.getTotalCost();
        }
        return total;
    }
} 